﻿using System;
using NUnit.Framework;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Bus.MessageManagement;

namespace SimpleServiceBus.Tests.Bus.MessageManagement
{
    [TestFixture]
    public class MessageTypePredicateTestFixture
    {
        [Test]
        public void Matches_Exact_Type()
        {
            var mtp = new MessageTypePredicate {MessageType = typeof (Sub)};

            Assert.IsTrue(mtp.Matches(MakeEnvelope<Sub>()));

            Assert.IsFalse(mtp.Matches(MakeEnvelope<AllFamilies>()));
            Assert.IsFalse(mtp.Matches(MakeEnvelope<Message_A>()));
            Assert.IsFalse(mtp.Matches(MakeEnvelope<Message_B>()));
        }

        [Test]
        public void Matches_Derived_Types()
        {
            var mtp = new MessageTypePredicate {MessageType = typeof (AllFamilies)};

            Assert.IsTrue(mtp.Matches(MakeEnvelope<Sub>()));
            Assert.IsTrue(mtp.Matches(MakeEnvelope<AllFamilies>()));

            Assert.IsFalse(mtp.Matches(MakeEnvelope<Message_A>()));
            Assert.IsFalse(mtp.Matches(MakeEnvelope<Message_B>()));
        }

        [Test]
        public void Matches_Interfaces()
        {
            var mtp = new MessageTypePredicate { MessageType = typeof(IMessageFamily_A) };

            Assert.IsTrue(mtp.Matches(MakeEnvelope<Sub>()));
            Assert.IsTrue(mtp.Matches(MakeEnvelope<AllFamilies>()));
            Assert.IsTrue(mtp.Matches(MakeEnvelope<Message_A>()));

            Assert.IsFalse(mtp.Matches(MakeEnvelope<Message_B>()));
        }

        private static MessageEnvelope MakeEnvelope<T>()
        {
            object message = Activator.CreateInstance(typeof (T));
            return new MessageEnvelope {Body = message};
        }
    }

    public interface IMessageFamily_A {}
    public interface IMessageFamily_B {}
    [Serializable]
    public class AllFamilies : IMessageFamily_A,IMessageFamily_B {}
    [Serializable]
    public class Message_A: IMessageFamily_A {}
    [Serializable]
    public class Message_B: IMessageFamily_B {}
    [Serializable]
    public class Sub : AllFamilies {}

    
}
